package fft;

/**
 * A abstract field.
 * @author traeger, balesterieri
 *
 * @param <F> set on which the field is defined.
 */
public abstract class Field<F> {
	/*
	 * Constants
	 */
	
	/**
	 * The zero. Neutral element of the add operation.
	 */
	public abstract F zero();
	/**
	 * The one. Neural element of the multiply operation.
	 * @return
	 */
	public abstract F one();
	
	/*
	 * Axioms
	 */
	
	/**
	 * Add operation.
	 */
	public abstract F add(F a, F b);
	/**
	 * Inverse of add operation.
	 */
	public abstract F inverseAdd(F a);
	/**
	 * Multiply operation.
	 */
	public abstract F mul(F a, F b);
	/**
	 * Inverse of multiply operation.
	 */
	public abstract F inverseMul(F a);
	/**
	 * Subtract operation.
	 */
	public F sub(F a, F b) {
		return add(a, inverseAdd(b));
	}
	/**
	 * Divide operation.
	 */
	public F div(F a, F b) {
		return mul(a, inverseMul(b));
	}
	/**
	 * Square operation.
	 * <tt>a*a</tt>
	 */
	public F square(F a) {
		return mul(a, a);
	}
	/**
	 * Add one n times to zero.
	 * @param n
	 * @return
	 */
	public F addOneNTimes(int n) {
		F z = zero();
		F one = one();
		for(int i = 0; i < n; i++)
			z = add(z, one);
		return z;
	}
}
